<template>
  <div id="container" :style="{ height: height + 'px' }"></div>
  <div :class="active_float_board ? 'float_board' : 'float_board_none'">
    <el-progress
      percentage="50"
      show-text="false"
      status="success"
      indeterminate="true"
      duration="1"
      v-if="process_contral"
      style="width: 100%"
    />
    <div class="mapstyle">
      <el-radio v-model="mapstyle" label="force" border>力引导图</el-radio>
      <el-radio v-model="mapstyle" label="circular" border>圆图</el-radio>
    </div>
    <div class="contralboard">
      <div v-if="show_slider" class="slider-block">
        <span class="demonstration">外观调节:</span>
        <el-slider :min="20" :max="80" v-model="force_num" />
      </div>
      <div class="slider-block">
        <span class="demonstration">节点数量调节({{ max_num }}):</span>
        <el-slider v-model="node_num" :max="max_num" :min="1" />
      </div>
      <el-row class="mb-4">
        <el-popover
          v-model:visible="flush_pop_visible"
          placement="right"
          title="重载"
          :width="180"
          content="节点数目已经改变，点击重载！！"
        >
          <template #reference>
            <el-button plain type="warning" @click="flush()">
              重载图谱
            </el-button>
          </template>
        </el-popover>
        <el-button plain type="success" @click="to_export_page()">
          导出图谱>>
        </el-button>
      </el-row>
    </div>
  </div>
</template>
<script>
import * as echarts from "echarts/core";
import {
  TitleComponent,
  TooltipComponent,
  LegendComponent,
  ToolboxComponent,
} from "echarts/components";
import { GraphChart } from "echarts/charts";
import { CanvasRenderer } from "echarts/renderers";
import { ref } from "vue";
export default {
  props: {
    height: Number,
    search_content: String,
    main_node_num: Number,
    graph_event_handler: {
      type: Function,
      default: null,
    },
  },
  name: "EGraph",
  data() {
    return {
      data: [],
      option: {},
      myChart: null,
      mapstyle: ref("force"),
      force_num: ref(30),
      node_num: ref(10),
      max_num: ref(50),
      show_slider: ref(true),
      process_contral: ref(false),
      flush_pop_visible: ref(false),
      active_float_board: ref(true),
    };
  },
  watch: {
    search_content: function (newvalue, oldvalue) {
      this.re_draw(newvalue);
    },
    max_num: function (newvalue, oldvalue) {
      if (newvalue == 0 || (oldvalue == 0 && newvalue == 1)) {
        this.max_num = 1;
        this.active_float_board = false;
      } else {
        this.active_float_board = true;
      }
      var ratio = this.node_num / oldvalue;
      var temp = Math.floor(newvalue * ratio);
      if (this.search_content=="[-all-]") {
        this.node_num =temp==0 ? newvalue:temp;
      }
      if (oldvalue > 50) {
        this.flush_pop_visible = true;
      }
    },
    main_node_num: function (newvalue, oldvalue) {
      // console.log("node num set in main node num change");
      this.node_num.value = newvalue;
    },
    mapstyle: function (newvalue, oldvalue) {
      this.process_contral = true;
      if (newvalue == "force") {
        this.show_slider = true;
      } else {
        this.show_slider = false;
      }
      this.re_draw_graph();
      this.process_contral = false;
    },
  },
  // created(){
  //   console.log("egraph creat");
  // },
  mounted() {
    // console.log("egraph mounted graph", this.search_content);
    echarts.use([
      TitleComponent,
      TooltipComponent,
      LegendComponent,
      GraphChart,
      CanvasRenderer,
      ToolboxComponent,
    ]);
    if (this.search_content) {
      this.get_graph(this.search_content);
    }
  },
  methods: {
    flush: function () {
      this.flush_pop_visible = false;
      if (this.search_content) {
        this.get_graph(this.search_content);
      }
    },
    to_export_page() {
      this.$router.push({
        name: "Export",
        params: {
          body: JSON.stringify({
            search_content: this.search_content,
            search_length: this.node_num,
            appearance: this.force_num,
            current_show: true,
          }),
        },
      });
    },
    initGraphOption: function (data) {
      data.nodes.forEach(function (node) {
        (node.draggable = true),
          (node.label = {
            show: node.symbolSize >= 1,
          });
      });
      let option = {
        title: {
          text: this.search_content,
          subtext: "Default layout",
          top: "bottom",
          left: "right",
        },
        tooltip: {
          // triggerOn: "none",
          formatter: function (x) {
            return x.data.name;
          },
        },
        toolbox: {
          // 显示工具箱
          show: true,
          feature: {
            mark: {
              show: true,
            },
            // 保存为图片
            saveAsImage: {
              show: true,
            },
          },
        },
        // legend: [
        //   {
        //     // selectedMode: 'single',
        //     data: data.categories.map(function (a) {
        //       return a.name;
        //     }),
        //   },
        // ],
        animationDurationUpdate: function (idx) {
          // 越往后的数据延迟越大
          return idx * 4;
        },
        // animationEasingUpdate: "bounceIn",
        animationDuration: 700,
        animationEasingUpdate: "quinticInOut",
        series: [
          {
            name: "",
            type: "graph",
            layout: this.mapstyle, //none  circular  force
            force: {
              repulsion: 3 * this.force_num, //节点之间的斥力因子
              edgeLength: this.force_num,
            },
            data: data.nodes,
            links: data.links,
            categories: data.categories,
            roam: true, // 是否开启鼠标缩放和平移漫游
            edgeSymbol: ["none", "none"], //['circle', 'arrow']   边两端的标记类型,可以是一个数组分别指定两端,也可以是单个统一指定
            label: {
              show: true,
              position: "right", //right
              formatter: "{b}",
              fontSize: 11,
              fontStyle: "400",
            },
            lineStyle: {
              color: "source",
              curveness: 0.3,
            },
            emphasis: {
              focus: "adjacency",
              lineStyle: {
                width: 10,
              },
            },
          },
        ],
      };
      return option;
    },

    get_graph(search_content) {
      var ROOT_PATH = "/api/search";
      // "https://cdn.jsdelivr.net/gh/apache/echarts-website@asf-site/examples";
      if (this.myChart == null) {
        var chartDom = document.getElementById("container");
        this.myChart = echarts.init(chartDom);
      }
      let t_node_num = 50;
      if (this.node_num > 0) {
        t_node_num = this.node_num;
      }
      this.$axios
        // .get(ROOT_PATH + "/data/asset/data/les-miserables.json")
        .post(ROOT_PATH, {
          search_content: search_content,
          search_length: t_node_num,
        })
        .then((graph) => {
          // console.log("graph", graph);
          if (!graph.data.success) {
            this.$notify.error({ title: "图谱消息:", message: graph.data.msg });
          }
          this.data = graph.data.data;
          this.max_num = graph.data.alldatalength;
          this.option = this.initGraphOption(this.data);
          this.myChart.setOption(this.option);
          // 回调函数 将当前节点展示的节点数，搜索内容，总共节点数返回
          if (this.graph_event_handler) {
            this.graph_event_handler(
              this.search_content,
              this.node_num,
              this.max_num
            );
          }
        });
    },
    re_draw_graph() {
      this.option = this.initGraphOption(this.data);
      this.option && this.myChart.setOption(this.option, true);
    },
    re_draw(search_content) {
      this.data = [];
      this.get_graph(search_content);
    },
  },
};
</script>

<style scoped>
#container {
  box-sizing: border-box;
  width: 100%;
}
.float_board {
  position: absolute;
  float: left;
  padding: 15px;
  width: 215px;
  margin-left: 17px;
  margin-top: 60px;
  background-color: rgba(255, 255, 255, 0.65);
  border: 1px solid rgba(204, 204, 204, 0.3);
  border-radius: 15px;
  pointer-events: auto;
}
.float_board_none {
  position: absolute;
  float: left;
  padding: 15px;
  width: 215px;
  margin-left: 17px;
  margin-top: 60px;
  background-color: rgba(236, 236, 236, 0.399);
  border: 1px solid rgba(255, 0, 0, 0.282);
  border-radius: 15px;
  pointer-events: none;
  opacity: 50%;
}
.float_board_none > * {
  opacity: 50%;
}
.mapstyle {
  width: 100%;
  height: 100%;
}
.contralboard {
  margin-top: 15px;
  width: 100%;
  height: fit-content;
}

.slider-block {
  display: flex;
  flex-direction: column;
  align-items: left;
  margin-bottom: 10px;
  margin-right: 5px;
  border-left: 2px solid rgb(93, 92, 92);
}
.slider-block .el-slider {
  margin-top: 0;
  margin-left: 5px;
}
.slider-block .demonstration {
  font-size: 15px;
  color: var(--el-text-color-secondary);
  line-height: 44px;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  margin-left: 5px;
}
</style>
